#!/bin/bash

# 数据库配置
USERNAME=ky_zdly  # 用户名
PWD=nBzV5ZXZ2nuE3C1VyxVX  # 密码
HOST=10.19.206.84  # ip
PORT=3306 # 端口

# 钉钉推送配置
appId="1111"
chatId="chatced4e6204ebdeaac3a4f7cfd865ef61a"
url='http://uatdingtalk.yundasys.com:9091/groupMsg/sendTextMsgByAppId'
max_send_limit=4950 # 钉钉实际推送字符上限是5000，剩余50是可能推送其他说明字符

# 日志路径（文件夹）
SLOW_QUERY_DIR="/yd/test_log/slow_query`date +'%Y%m'`"
SQL_PROCESS_DIR="/yd/test_log/sql_process`date +'%Y%m'`"

if [ ! -d "$SLOW_QUERY_DIR" ]; then
	mkdir -p "$SLOW_QUERY_DIR"
fi

if [ ! -d "$SQL_PROCESS_DIR" ]; then
        mkdir -p "$SQL_PROCESS_DIR"
fi

# 日志文件
SLOW_QUERY_LOG=$SLOW_QUERY_DIR"/`date +'%d'`.log"
SQL_PROCESS_LOG=$SQL_PROCESS_DIR"/`date +'%d'`.log"

if [ ! -f "$SLOW_QUERY_LOG" ]; then
        touch "$SLOW_QUERY_LOG"
fi

if [ ! -f "$SQL_PROCESS_LOG" ]; then
        touch "$SQL_PROCESS_LOG"
fi


# 超时限制（超过30s的sql即预警）
TIMEOUT_LIMIT=30
# 进程数限制（超过50个即预警）
THREADS_CONNECTED_LIMIT=50


# 获取当前数据库连接数
sql_threads_connected=`mysql -u${USERNAME} -p${PWD} -h${HOST} -P${PORT} -s -e "show status;"|grep Threads_connected|awk '{print $2}'`
if [ $sql_threads_connected -ge $THREADS_CONNECTED_LIMIT ]; then
	echo -e "\n`date +'%Y-%m-%d %H:%M:%S'` MySQL Threads_connected number:${sql_threads_connected}" >> ${SQL_PROCESS_LOG}
	err_msg="当前数据库连接数：${sql_threads_connected}" # 需要发送的通知信息
        request_data="{'appId':'"$appId"','chatId':'"$chatId"','content':'"$err_msg"'}" # 消息体
        response_data=`curl -H "Content-Type: application/json" -s -X POST -d $request_data $url` # 响应值
        echo -e "【响应值】：$response_data" >> ${SQL_PROCESS_LOG} # 将响应值写入log
fi 


# 获取当前时间点执行时间超过30s的sql语句
slow_query_sql=`mysql -u${USERNAME} -p${PWD} -h${HOST} -P${PORT} -s -e "select time,info from information_schema.processlist where info is not null and time > ${TIMEOUT_LIMIT};"`


IFS_old=$IFS      # 记录老的分隔符
IFS=$'\n'         # 以换行符作为分隔符

# 遍历
for loop in $slow_query_sql
do
	IFS=$'\t'  # 以制表符作为分隔符
	arr=($loop) # 初始化数组（0为执行时间，下标1为慢查询sql语句）
	
	# 记录日志
	echo -e "\n`date +'%Y-%m-%d %H:%M:%S'`" >> $SLOW_QUERY_LOG
        echo -e "【执行时间】：${arr[0]}s\n【执行SQL】：${arr[1]}" >> $SLOW_QUERY_LOG

	# 如果字符不超过钉钉最大推送字符，就直接推送（钉钉推送消息最长只能5000字符）
	sql_length=${#arr[1]} # 需要推送sql长度
	if [ $sql_length -lt $max_send_limit ];then
            
	    err_msg="慢查询：${arr[1]}(${arr[0]}s)" # 需要发送的通知信息
	    request_data="{'appId':$appId,'chatId':$chatId,'content':$err_msg}" # 消息体
            response_data=`curl -H "Content-Type: application/json" -s -X POST -d $request_data $url` # 响应值
	    echo -e "【响应值】：$response_data" >> $SLOW_QUERY_LOG # 将响应值写入log

	else

	    # 超过最大传输字符，则分段推送
	    cycle=`expr $sql_length / $max_send_limit`
	    echo -e "【sql超长，需要分段推送】：段数为$(($cycle + 1))" >> $SLOW_QUERY_LOG
	    
	    for((i=0;i<=$cycle;i++));
	    do
		
		itc_start=`expr $i \* $max_send_limit` # itc即intercept
		itc_str="${arr[1]:$itc_start:$max_send_limit}"
		# 如果需要推送的sql长度超过max_send_limit同时又是它的整数倍，则会导致最后一条推送信息为空
		if [ ${#itc_str} -gt 0 ];then
			
		    err_msg="$itc_str(no${i})"
		    request_data="{'appId':$appId,'chatId':$chatId,'content':$err_msg}" # 消息体
                    response_data=`curl -H "Content-Type: application/json" -s -X POST -d $request_data $url` # 响应值
                    echo -e "【第${i}段响应值】：$response_data" >> $SLOW_QUERY_LOG # 将响应值写入log

		fi
		
	    done

	fi

done

IFS=$IFS_old # 恢复
